package cn.yx.common.mail.service;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.yx.common.core.exception.CommonException;
import cn.yx.common.mail.constant.message.MailSendServiceMessageKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.List;

/**
 * <p>邮件发送服务类</p>
 *
 * @author Wgssmart
 */
@Component
@Slf4j
public class MailSendService {

    private final JavaMailSender javaMailSender;
    private final MailProperties mailProperties;

    public MailSendService(JavaMailSender javaMailSender, MailProperties mailProperties) {
        this.javaMailSender = javaMailSender;
        this.mailProperties = mailProperties;
    }

    /**
     * 指定单个收件人发送文本邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     */
    public void send(String to, String subject, String text) {
        send(to, null, null, subject, text);
    }

    /**
     * 指定单个收件人和单个抄送人发送文本邮件
     *
     * @param to      收件人
     * @param cc      抄送人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     */
    public void send(String to, String cc, String subject, String text) {
        send(to, cc, null, subject, text);
    }

    /**
     * 指定单个收件人、单个抄送人和单个密送人发送文本邮件
     *
     * @param to      收件人
     * @param cc      抄送人
     * @param bcc     密送人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     */
    public void send(String to, String cc, String bcc, String subject, String text) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(mailProperties.getUsername());
        simpleMailMessage.setTo(to);
        if (StrUtil.isNotEmpty(cc)) {
            simpleMailMessage.setCc(cc);
        }
        if (StrUtil.isNotEmpty(bcc)) {
            simpleMailMessage.setBcc(bcc);
        }
        simpleMailMessage.setSubject(subject);
        simpleMailMessage.setText(text);
        javaMailSender.send(simpleMailMessage);
    }

    /**
     * 指定多个收件人发送文本邮件
     *
     * @param toArray 多个收件人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     */
    public void send(String[] toArray, String subject, String text) {
        send(toArray, null, null, subject, text);
    }

    /**
     * 指定多个收件人和多个抄送人发送文本邮件
     *
     * @param toArray 多个收件人
     * @param ccArray 多个抄送人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     */
    public void send(String[] toArray, String[] ccArray, String subject, String text) {
        send(toArray, ccArray, null, subject, text);
    }

    /**
     * 指定多个收件人、多个抄送人，多个密送人发送文本邮件
     *
     * @param toArray  多个收件人
     * @param ccArray  多个抄送人
     * @param bccArray 多个密送人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     */
    public void send(String[] toArray, String[] ccArray, String[] bccArray, String subject, String text) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(mailProperties.getUsername());
        simpleMailMessage.setTo(toArray);
        if (ArrayUtil.isNotEmpty(ccArray)) {
            simpleMailMessage.setCc(ccArray);
        }
        if (ArrayUtil.isNotEmpty(bccArray)) {
            simpleMailMessage.setBcc(bccArray);
        }
        simpleMailMessage.setSubject(subject);
        simpleMailMessage.setText(text);
        javaMailSender.send(simpleMailMessage);
    }

    /**
     * 指定单个收件人发送带附件邮件
     *
     * @param to      单个收件人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     * @param file    附件文件
     */
    public void send(String to, String subject, String text, File file) {
        send(to, null, null, subject, text, file);
    }

    /**
     * 指定单个收件人和单个抄送人发送带附件邮件
     *
     * @param to      单个收件人
     * @param cc      单个抄送人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     * @param file    附件文件
     */
    public void send(String to, String cc, String subject, String text, File file) {
        send(to, cc, null, subject, text, file);
    }

    /**
     * 指定单个收件人、单个抄送人，单个密送人发送带附件邮件
     *
     * @param to      单个收件人
     * @param cc      单个抄送人
     * @param bcc     单个密送人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     * @param file    附件文件
     */
    public void send(String to, String cc, String bcc, String subject, String text, File file) {
        List<File> fileList = List.of(file);
        send(to, cc, bcc, subject, text, fileList);
    }

    /**
     * 指定多个收件人发送带附件邮件
     *
     * @param toArray 多个收件人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     * @param file    附件文件
     */
    public void send(String[] toArray, String subject, String text, File file) {
        send(toArray, null, null, subject, text, file);
    }

    /**
     * 指定多个收件人、多个抄送人发送带附件邮件
     *
     * @param toArray 多个收件人
     * @param ccArray 多个抄送人
     * @param subject 主题
     * @param text    文本，可以是HTML或普通文本
     * @param file    附件文件
     */
    public void send(String[] toArray, String[] ccArray, String subject, String text, File file) {
        send(toArray, ccArray, null, subject, text, file);
    }

    /**
     * 指定多个收件人、多个抄送人，多个密送人发送带附件邮件
     *
     * @param toArray  多个收件人
     * @param ccArray  多个抄送人
     * @param bccArray 多个密送人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param file     附件文件
     */
    public void send(String[] toArray, String[] ccArray, String[] bccArray, String subject, String text, File file) {
        List<File> fileList = List.of(file);
        send(toArray, ccArray, bccArray, subject, text, fileList);
    }

    /**
     * 指定单个收件人发送带附件邮件
     *
     * @param to       单个收件人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param fileList 多个附件文件
     */
    public void send(String to, String subject, String text, List<File> fileList) {
        send(to, null, null, subject, text, fileList);
    }

    /**
     * 指定单个收件人和单个抄送人发送带附件邮件
     *
     * @param to       单个收件人
     * @param cc       单个抄送人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param fileList 多个附件文件
     */
    public void send(String to, String cc, String subject, String text, List<File> fileList) {
        send(to, cc, null, subject, text, fileList);
    }

    /**
     * 指定单个收件人、单个抄送人，单个密送人发送带附件邮件
     *
     * @param to       单个收件人
     * @param cc       单个抄送人
     * @param bcc      单个密送人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param fileList 多个附件文件
     */
    public void send(String to, String cc, String bcc, String subject, String text, List<File> fileList) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(mailProperties.getUsername());
            mimeMessageHelper.setTo(to);
            if (StrUtil.isNotEmpty(cc)) {
                mimeMessageHelper.setCc(cc);
            }
            if (StrUtil.isNotEmpty(bcc)) {
                mimeMessageHelper.setBcc(bcc);
            }
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(text);
            for (File file : fileList) {
                mimeMessageHelper.addAttachment(file.getName(), file);
            }
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("send file mail error", e);
            // @SimplifiedChinese=邮件发送异常
            // @English=Send email error
            throw new CommonException(MailSendServiceMessageKey.SEND_MAIL_ERROR, e);
        }
    }

    /**
     * 指定多个收件人发送带附件邮件
     *
     * @param toArray  多个收件人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param fileList 多个附件文件
     */
    public void send(String[] toArray, String subject, String text, List<File> fileList) {
        send(toArray, null, null, subject, text, fileList);
    }

    /**
     * 指定多个收件人和多个抄送人发送带附件邮件
     *
     * @param toArray  多个收件人
     * @param ccArray  多个抄送人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param fileList 多个附件文件
     */
    public void send(String[] toArray, String[] ccArray, String subject, String text, List<File> fileList) {
        send(toArray, ccArray, null, subject, text, fileList);
    }

    /**
     * 指定多个收件人、多个抄送人和多个密送人发送带附件邮件
     *
     * @param toArray  多个收件人
     * @param ccArray  多个抄送人
     * @param bccArray 多个密送人
     * @param subject  主题
     * @param text     文本，可以是HTML或普通文本
     * @param fileList 多个附件文件
     */
    public void send(String[] toArray, String[] ccArray, String[] bccArray, String subject, String text, List<File> fileList) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(mailProperties.getUsername());
            mimeMessageHelper.setTo(toArray);
            if (ArrayUtil.isNotEmpty(ccArray)) {
                mimeMessageHelper.setCc(ccArray);
            }
            if (ArrayUtil.isNotEmpty(bccArray)) {
                mimeMessageHelper.setBcc(bccArray);
            }
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(text);
            for (File file : fileList) {
                mimeMessageHelper.addAttachment(file.getName(), file);
            }
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("send file mail error", e);
            throw new CommonException(MailSendServiceMessageKey.SEND_MAIL_ERROR, e);
        }
    }

}
